/*
**			Heroes IV
**	  Copyright 2001, The 3DO Company
**
**  creature_info_window.cpp
**
*/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "creature_info_window.h"

#include "abbreviate_number.h"
#include "adaptor_handler.h"
#include "bitmap_group.h"
#include "bitmap_group_cache.h"
#include "bitmap_layer_cache_window.h"
#include "bound_handler.h"
#include "button.h"
#include "creature.h"
#include "creature_array_window.h"
#include "creature_traits.h"
#include "creature_type.h"
#include "external_string.h"
#include "format_string.h"
#include "game_window.h"
#include "hero.h"
#include "mouse_event.h"
#include "replace_keywords.h"
#include "simple_dialog.h"
#include "standard_fonts.h"
#include "text_window.h"

extern  t_bitmap_group_cache g_divide_cursor;
extern  t_bitmap_group_cache g_creature_rings;

//extern t_external_string const k_text_spell_points;
//extern t_external_string const k_text_hit_points;

/*
** Button for creature portrait array.
*/
namespace
{
    const   int k_quantity_text_offset = 12;

	class t_portrait_window : public t_window
	{
	public:
		t_portrait_window( t_screen_rect const& rect, t_creature_info_window* parent,
		               int slot );

		//virtual void drag_event( t_mouse_event const& event );
	    virtual void left_button_down( t_mouse_event const& event );
		virtual void left_button_up( t_mouse_event const& event );
		virtual void left_double_click( t_mouse_event const& event );
		virtual void mouse_move( t_mouse_event const& event );
	    virtual void mouse_leaving( t_window* old_window, t_window* new_window,
		                            t_mouse_event const& event );
 	protected:
		void select();

		t_creature_info_window* m_array_window;
		int                      m_portrait_slot_index;
	};


};

t_portrait_window::t_portrait_window( t_screen_rect const& rect, t_creature_info_window* parent,
							 int slot ) : t_window( rect, k_some_transparency, parent )
{
	m_array_window = parent;
	m_portrait_slot_index = slot;
}


void t_portrait_window::left_button_down( t_mouse_event const& event )
{
	select();
}

void t_portrait_window::left_button_up( t_mouse_event const& event )
{
	select();
}

void t_portrait_window::left_double_click( t_mouse_event const& event )
{
}

void t_portrait_window::select()
{
	t_creature_array const* army = m_array_window->get_army();

	if (army == 0 || (*army)[m_portrait_slot_index].get_number() == 0)
		return;
	m_array_window->select_creature( m_portrait_slot_index );
}

void t_portrait_window::mouse_move( t_mouse_event const& event )
{
}

void t_portrait_window::mouse_leaving( t_window* old_window, t_window* new_window,
		                           t_mouse_event const& event )
{
}

/*----------------------------------------------------------------------------*\
**
** Window for displaying creatures.
**
\*----------------------------------------------------------------------------*/
t_creature_info_window::t_creature_info_window( t_screen_point const& origin, 
		                                          t_creature_array const * army,
                                                  t_skill_mastery scout_skill_level,
												  t_layout layout, 
												  t_window* parent )
					   : t_window( t_screen_rect(origin.x, origin.y, origin.x, origin.y),
					               k_completely_transparent, parent ), m_army( army )
{
	m_rings = g_creature_rings.get();
	m_selected_slot = -1;
    m_scouting_skill_level = scout_skill_level;

	// create portraits / buttons
	int            i;
	t_screen_point point;

	static char const* k_names[3][3] = 
	{
		{ "top_left",		"top",		"top_right" },
		{ "left",			"middle",	"right" },
		{ "bottom_left",	"bottom",	"bottom_right" }
	};

	static int const k_layout[4][k_number_of_creature_portraits][2] =
	{
		{{ 1, 0 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 2 }},
		{{ 0, 0 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 2 }},
		{{ 2, 0 }, { 2, 1 }, { 2, 1 }, { 2, 1 }, { 2, 1 }, { 2, 1 }, { 2, 2 }},
		{{ 0, 0 }, { 2, 0 }, { 0, 1 }, { 2, 1 }, { 0, 1 }, { 2, 2 }, { 1, 2 }}
	};

	t_bitmap_layer const* layer[3][3];
	t_bitmap_layer const* highlight[3][3];
	int                   row;
	int                   column;
	std::string           layer_name;

	// load layers from border file
	for (row = 0; row < 3; row++)
	{
		for (column = 0; column < 3; column++)
		{
			layer_name = k_names[row][column];
			layer[row][column] = m_rings->find( layer_name );
			layer_name += "_highlight" ;
			highlight[row][column] = m_rings->find( layer_name );
		}
	}

	// find the offset of the portrait relative to the border
	t_screen_rect           portrait_rect = m_rings->find( "portrait" )->get_rect();
	t_screen_point          portrait_offset = portrait_rect.top_left();
	t_screen_point          border_offset;
	t_bitmap_layer const*   border;
	t_bitmap_layer const*   inset = m_rings->find( "inset" );
	t_bitmap_layer const*   inset_text = m_rings->find( "inset_text" );
	t_screen_point          inset_offset = inset->get_rect().top_left();
	t_screen_rect           text_rect = inset_text->get_rect() - inset_offset;
	t_cached_font           font = get_font( text_rect.height() );
	t_screen_rect           number_rect = m_rings->find( "number_text" )->get_rect();
	//t_window *              window_ptr;

	point.x = 0;
	point.y = 0;
	for (i = 0; i < k_number_of_creature_portraits; i++)
	{
		t_creature_portrait_window& portrait_slot = m_portrait_slots[i];
	    t_screen_point   quantity_text_point;

		row = k_layout[layout][i][0];
		column = k_layout[layout][i][1];
		// get the appropriate border
		border = layer[row][column];
		// make upper left corner of border == point
		border_offset = -border->get_rect().top_left();

		// create a transparent "drop target" behind button to shunt messages to button
		// when it's invisible.
		t_window* drop_target;
		
		drop_target = new t_portrait_window( point + portrait_rect + border_offset, this, i );
		// create button
		portrait_slot.portrait_window = new t_bitmap_layer_cache_window( t_bitmap_layer_ptr(),
			                       t_screen_point(0,0), drop_target );

		// create border
		portrait_slot.border = new t_bitmap_layer_window( border, point + border_offset, this );
		// create highlighted border
		portrait_slot.selected = new t_bitmap_layer_window( highlight[row][column], 
			                                       point + border_offset, this );
		// hide highlighted border
		portrait_slot.selected->set_visible( false );

		// create text window
 		portrait_slot.text = new t_text_window( font, text_rect, this, "", t_pixel_24( 0,0,0 ) );
		portrait_slot.text->set_center_horizontal();
		portrait_slot.text->set_drop_shadow( true, t_pixel_24(200,200,200) );

        /*
        ** Set quantity text window.
        */
	    
		//window_ptr = new t_bitmap_layer_window( number_background_layer, point + border_offset, this );
 		portrait_slot.quantity_text = new t_text_window(  get_font( number_rect.height() ),
                        number_rect + point + border_offset, this, "", t_pixel_24( 0,0,0 ) );
		portrait_slot.quantity_text->set_center_horizontal();
		portrait_slot.quantity_text->set_drop_shadow( true, t_pixel_24(200,200,200) );

		if (layout != k_stacked_rows)
			point.x += border->get_width();
		else
		{
			if (row == 0)
				point.y += border->get_rect().height();
			else
			{
				point.x += m_portrait_slots[i-1].border->get_width();
				point.y -= layer[0][0]->get_rect().height();
			}
		}
	}

	set_size_from_children();
	update();
}


// ---------------------------------------------------------------------------
// window for displaying and manipulating lists of creatures
// ---------------------------------------------------------------------------
int t_creature_info_window::get_frame_height() const
{
	return m_portrait_slots[0].border->get_height();
}

t_creature_stack const *t_creature_info_window::get_selected_army() 
{
	//t_creature_stack const& creature = (*m_army)[m_selected_slot];

	if ((m_selected_slot >= 0) && (*m_army)[m_selected_slot].get_number() != 0)
    {
	    return &(*m_army)[m_selected_slot];
	    //return m_army[m_selected_slot];
    }
    else
    {
        return (NULL);
    }

}

// ---------------------------------------------------------------------------
// window for displaying and manipulating lists of creatures
// ---------------------------------------------------------------------------
void t_creature_info_window::update()
{
	int         i;
	std::string text;

	if (m_army == 0)
	{
		for (i = 0; i < k_number_of_creature_portraits; i++)
		{
			t_creature_portrait_window& portrait_slot = m_portrait_slots[i];

			portrait_slot.portrait_window->set_bitmap( t_bitmap_layer_ptr() );
			portrait_slot.portrait_window->set_help_balloon_text( "" );
		}
		set_cursor( get_cursor( false ) );
		select_creature( -1 );
		return;
	}

	for (i = 0; i < k_number_of_creature_portraits; i++)
	{
        t_screen_point  text_point;
		t_creature_portrait_window&     portrait_slot = m_portrait_slots[i];
		t_creature_stack const& creature = (*m_army)[i];
	    t_hero const* hero = creature.get_hero();

		std::string right_click_text = creature.get_right_click_text();

		portrait_slot.portrait_window->set_bitmap( creature.get_portrait() );

        text_point = portrait_slot.portrait_window->get_screen_rect().top_left();
        //text_point += t_screen_point (0, (portrait_slot.portrait_window->get_height()));
 		//portrait_slot.quantity_text->move(text_point);

		if (hero)
        {
		    portrait_slot.quantity_text->set_text( "" );
			text = creature.get_name();
			portrait_slot.portrait_window->set_help_balloon_text( text );
			portrait_slot.portrait_window->set_right_click_text( right_click_text );
        }
        else if (creature.get_number() == 0)
		{
			portrait_slot.portrait_window->set_help_balloon_text( "" );
			portrait_slot.portrait_window->set_right_click_text( right_click_text );
		    portrait_slot.quantity_text->set_text( "" );
		}
        else
		{
			if (creature.get_creature() == 0 )
			{
				text = creature.get_name();
				portrait_slot.text->set_visible( false );
			}
			else if (m_scouting_skill_level >= k_mastery_advanced)
			{
				text = creature.get_name();
			    portrait_slot.quantity_text->set_text( format_string( "%i ", creature.get_number()) );
			    //portrait_slot.quantity_text->set_text( abbreviate_number( creature.get_number() ) );
            }
            else
            {
				text = creature.get_name( false, 2 ); // Force plural
				portrait_slot.quantity_text->set_font( get_font( 12 ) ); // Longer names = smaller font
			    portrait_slot.quantity_text->set_text( get_army_size_name( creature.get_number(), k_article_none ) );
            }
			portrait_slot.portrait_window->set_help_balloon_text( text );
			portrait_slot.portrait_window->set_right_click_text( right_click_text );
		}
	}

	if (m_selected_slot >= 0 && (*m_army)[m_selected_slot].get_number() == 0)
		select_creature( -1 );
}

// ---------------------------------------------------------------------------
// window for displaying and manipulating lists of creatures
// ---------------------------------------------------------------------------
void t_creature_info_window::set_highlight( int index, bool highlight )
{
	t_creature_portrait_window& slot = m_portrait_slots[index];

	slot.border->set_visible( !highlight );
	slot.selected->set_visible( highlight );
}

// ---------------------------------------------------------------------------
// window for displaying and manipulating lists of creatures
// ---------------------------------------------------------------------------
void t_creature_info_window::set_army( t_creature_array const * army )
{
	if (army == m_army)
		return;
	m_army = army;
	select_first();
	update();
}

// ---------------------------------------------------------------------------
// window for displaying and manipulating lists of creatures
// ---------------------------------------------------------------------------
void t_creature_info_window::set_scouting_level( t_skill_mastery scout_skill_level )
{
	if ( m_scouting_skill_level == scout_skill_level )
		return;

	m_scouting_skill_level = scout_skill_level;
	update();
}

// ---------------------------------------------------------------------------
// window for displaying and manipulating lists of creatures
// ---------------------------------------------------------------------------
void t_creature_info_window::select_first()
{
	int i;

	if (m_army == 0)
		return;

	for (i = 0; i < k_number_of_creature_portraits; i++)
	{
		if ((*m_army)[i].get_number() > 0)
			break;
	}
	if (i == k_number_of_creature_portraits)
		i = -1;
	select_creature( i );
}

/*
** Player clicked on a creature portrait.
*/
void t_creature_info_window::select_creature( int index )
{
	int i;

	for (i = 0; i < k_number_of_creature_portraits; i++)
		set_highlight( i, i == index );
	m_selected_slot = index;

    // Let handler know.
	m_select_handler( this, index );
}


